using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Bomberman;
using BombermanControlador;
using System.Windows.Forms;

namespace BombermanGame
{

	public delegate void BeforeUpdateEventHandler(object sender, BeforeUpdateEventArgs args);

	
	public class BeforeUpdateEventArgs : System.EventArgs
	{
		public KeyboardState KeyboardState { get { return Keyboard.GetState(); } }
		public MouseState MouseState { get { return Mouse.GetState(); } }
	}


	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class Game : Microsoft.Xna.Framework.Game
	{
		private const int AnchoBarraOpciones = 150;

		GraphicsDeviceManager graphics;
		SpriteBatch spriteBatch;
		BombermanJuego juego;
		MapaGraph mapaGraph;
		Menu form;
		SoundHandler soundHandler;
		
		public event BeforeUpdateEventHandler BeforeUpdate;

        public Game(BombermanJuego juego, Menu form)
        {
            this.form = form;
		this.form.BombermanJuego = juego;

            Form xnaWindow = (Form)Control.FromHandle((this.Window.Handle));
            xnaWindow.GotFocus += new EventHandler(xnaWindow_GotFocus);

            graphics = new GraphicsDeviceManager(this);
		graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
		
		soundHandler = new SoundHandler();
		soundHandler.MusicClick += new MusicBottonClickHandler(ChangeMusicState);
            
            Content.RootDirectory = "Content";
            this.juego = juego;

        }

        void xnaWindow_GotFocus(object sender, EventArgs e)
        {
            ((Form)sender).Visible = false;
            form.TopMost = false;
        }

        void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = form.Panel.Handle;
        }


		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize()
		{
			// TODO: Add your initialization logic here
			mapaGraph = new MapaGraph();

			this.Window.Title = "Bomberman";
			this.Window.AllowUserResizing = true;

			AjustarTamaniosVentana();

			InitializeMusic();

			base.Initialize();
		}

		private void AjustarTamaniosVentana()
		{
			graphics.PreferredBackBufferWidth = (juego.Mapa.DimencionX) * MapaGraph.anchoImagen;
			graphics.PreferredBackBufferHeight = (juego.Mapa.DimencionY) * MapaGraph.altoImagen;
			graphics.ApplyChanges();
			form.Panel.Width = graphics.PreferredBackBufferWidth;
			form.Panel.Height = graphics.PreferredBackBufferHeight;
		}

		private void InitializeMusic()
		{
			
				Song mainTheme = Content.Load<Song>("MainTheme");
			
				MediaPlayer.IsRepeating = true;

				MediaPlayer.Play(mainTheme);
			
		}
        
        
		private void ChangeMusicState(object sender, MusicBottonArgs state)
		{
			if (state.MusicState == false)
				MediaPlayer.Resume();
			else
			{
				MediaPlayer.Pause();
			}
        


		}
        
		/// <summary>
		/// LoadContent will be called once per game and is the place to load
		/// all of your content.
		/// </summary>
		protected override void LoadContent()
		{
			// Create a new SpriteBatch, which can be used to draw textures.
			spriteBatch = new SpriteBatch(GraphicsDevice);
			mapaGraph.LoadContent(Content);

			// TODO: use this.Content to load your game content here
		}

		/// <summary>
		/// UnloadContent will be called once per game and is the place to unload
		/// all content.
		/// </summary>
		protected override void UnloadContent()
		{
			// TODO: Unload any non ContentManager content here
		}

		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if ((GamePad.GetState(PlayerIndex.One).Buttons.Back == Microsoft.Xna.Framework.Input.ButtonState.Pressed) || form.Salir)
                this.Exit();
		
		soundHandler.Update();
		form.Update(juego.Jugador.Vida);

            if (form.Iniciado)
            {

                
                if (BeforeUpdate != null)
                {
                    RaiseUpdate();
		    }
             
                juego.Update();

            }
            base.Update(gameTime);

		if (!(juego.SigueActivo()))
		{
			MessageBox.Show("Usted ha muerto!! Game Over","Bomberman");
			Application.Exit();
		}
	 }

		private void RaiseUpdate()
		{
			BeforeUpdate(this, new BeforeUpdateEventArgs());
		}

		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            if (form.Iniciado)
            {
                spriteBatch.Begin();
		    mapaGraph.Draw(spriteBatch, juego.Mapa);
                spriteBatch.End();
            }
            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
	}
}
